package chat7me_1223.client;

import chat7me_1223.client.ui.LoginWindow;
import chat7me_1223.client.ui.RegWindow;
import chat7me_1223.client.ui.TalkWindow;
import chat7me_1223.client.util.IOUtil;

import javax.swing.*;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

//客户端的核心代码(包括引用了三个界面类的对象， 和一个负责接收服务端返回数据的线程GetServerMsgThread)
//1.本客户端在主线程中负责让某界面先显示，让某界面后显示(界面中的按钮监听代码中负责发送数据给服务端)。
//2.并且用线程接收服务端返回的数据。
public class Client {
    //编写客户端的所有代码顺序：复制工具类，然后写本类Client的成员变量和get set方法，和removeTalkWindowInClient(从聊天窗口集合中删除聊天窗口)方法
    //然后写三个界面(先写TalkWindow类)，不写监听代码
    //最后写本类中的start方法和线程代码
    //最后完成界面中监听器的代码

    // xxxxx然后写静态界面和每个页码的关闭方法及按钮的get和set方法及TalkWindow的showMessage方法和登录窗口的注册按钮监听代码和注册窗口登录按钮的按钮监听代码，最后写本类的线程，最后写界面的监听方法
    private LoginWindow loginWindow;
    private RegWindow regWindow;
    private  String loginUsername;
    private Socket socket;
    public static  final int PORT=8088;
    public static  final String IP="localhost";
    private  ReceiveServerMsgThread receiveServerMsgThread=null;

    private HashMap<String, TalkWindow>  allTalkWindow=new HashMap<String, TalkWindow>();
    private ArrayList<String>  onLineUserList=new ArrayList<>();

    //一定要注意： 服务端和客户端使用的这些常量值一定要一样(eg: LOGIN_REQUEST的值在服务端和客户端都要是1)
    //可以将这些变量放入到一个单独的java类中，这样服务端和客户端就可以复用这些常量值
    public static final  short  LOGIN_REQUEST=1;
    public static final  short  REGISTER_REQUEST=2;
    public static final  short  SEND_TEXT_REQUEST=3;

    public static final  short  LOGIN_RESPONSE=1;
    public static final  short  REGISTER_RESPONSE=2;
    public static final  short  SEND_TEXT_TO_ALL_RESPONSE=3;
    public static final  short  USER_LIST_RESPONSE=4;

    public static void main(String[] args) {
        Client client=new Client();
        LoginWindow loginWindow=new LoginWindow(client);

        client.setLoginWindow(loginWindow);
        client.start();
    }

    public Client(){
        createSocket();
    }
    public void createSocket() {
        try {
            if(socket==null){
                socket=new Socket(IP,PORT);
            }
        } catch (IOException e) {
            JOptionPane.showMessageDialog(null,"连接服务端异常,原因："+e.getMessage());
        }
    }

    public void start(){
        if(receiveServerMsgThread==null){
            receiveServerMsgThread=new ReceiveServerMsgThread();
            receiveServerMsgThread.start();
        }
    }


    public LoginWindow getLoginWindow() {
        return loginWindow;
    }

    public void setLoginWindow(LoginWindow loginWindow) {
        this.loginWindow = loginWindow;
    }

    public RegWindow getRegWindow() {
        return regWindow;
    }

    public void setRegWindow(RegWindow regWindow) {
        this.regWindow = regWindow;
    }

    public String getLoginUsername() {
        return loginUsername;
    }

    public void setLoginUsername(String loginUsername) {
        this.loginUsername = loginUsername;
    }

    public Socket getSocket() {
        return socket;
    }

    public void setSocket(Socket socket) {
        this.socket = socket;
    }

    public HashMap<String, TalkWindow> getAllTalkWindow() {
        return allTalkWindow;
    }

    public void setAllTalkWindow(HashMap<String, TalkWindow> allTalkWindow) {
        this.allTalkWindow = allTalkWindow;
    }

    public ArrayList<String> getOnLineUserList() {
        return onLineUserList;
    }

    public void setOnLineUserList(ArrayList<String> onLineUserList) {
        this.onLineUserList = onLineUserList;
    }



    public void removeTalkWindowInClient(TalkWindow talkWindow){
        Iterator<Map.Entry<String,TalkWindow>> ite=this.getAllTalkWindow().entrySet().iterator();
        while(ite.hasNext()){
            Map.Entry<String,TalkWindow> entry=ite.next();
            if(entry.getValue().equals(talkWindow)){
                ite.remove();
                break;
            }
        }
    }



    class ReceiveServerMsgThread extends  Thread{
        private InputStream in;
        ReceiveServerMsgThread(){
            try {
                in=socket.getInputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public void run() {


            try {
                int cmdFromServer=-1;
                String fromUsername = "";
                while (  (cmdFromServer=in.read())!=-1  ) {
                    switch (cmdFromServer){
                        case REGISTER_RESPONSE:
                            String resultStr= IOUtil.readString(in);
                            //！！一定要注意： 这里的字符串和服务端返回的字符串一定要一模一样,否则就不能正确处理服务端返回的消息
                            if("registerSuccess".equals(resultStr)){
                                JOptionPane.showMessageDialog(null,"恭喜您"+getLoginUsername()+"注册成功,聊天室欢迎您");
                                getRegWindow().closeRegWindow();
                                TalkWindow  talkWin=new TalkWindow(getLoginUsername(),"ALL",Client.this);
                                allTalkWindow.put("ALL",talkWin);
                            }else{
                                JOptionPane.showMessageDialog(null,"注册失败,原因"+resultStr);
                            }
                            break;
                        case LOGIN_RESPONSE:
                            String resultStr2= IOUtil.readString(in);
                            //！！一定要注意： 这里的字符串和服务端返回的字符串一定要一模一样,否则就不能正确处理服务端返回的消息
                            if(resultStr2.equals("loginSuccess")){
                                getLoginWindow().closeLoginWin();
                                TalkWindow  talkWin=new TalkWindow(getLoginUsername(),"ALL",Client.this);
                                allTalkWindow.put("ALL",talkWin);
                            }else{
                                JOptionPane.showMessageDialog(null, "登陆失败,原因:"+resultStr2);
                                getLoginWindow().getLoginBtn().setEnabled(true);
                                getLoginWindow().getRegisterBtn().setEnabled(true);
                            }
                            break;
                        case USER_LIST_RESPONSE:
                            String userListStr=IOUtil.readString(in);
                            String[]  friendsArr=userListStr.split(",");
                            if(friendsArr!=null && friendsArr.length>0){
                                ArrayList<String>  friendsList=new ArrayList<>();
                                setOnLineUserList(friendsList);
                                for(int i=0;i<friendsArr.length;i++){
                                    friendsList.add(friendsArr[i]);
                                }
                                setOnLineUserList(friendsList);
                            }
                            break;
                        case SEND_TEXT_TO_ALL_RESPONSE:
                            fromUsername=IOUtil.readString(in);
                            String messageToAllStr=IOUtil.readString(in);
                            TalkWindow talkWindow= getTalkWindowByTargetName("ALL");
                            talkWindow.showAllMessage(fromUsername,messageToAllStr);
                            break;
                    }
                }
            } catch (IOException e) {
                JOptionPane.showMessageDialog(null,"读取服务端信息异常，原因："+e.getMessage());
            }

        }


        private TalkWindow getTalkWindowByTargetName(String targetName){
            for(String  onLineUsername : allTalkWindow.keySet()){
                if(onLineUsername.equals(targetName)){
                    return allTalkWindow.get(targetName);
                }
            }
            return null;
        }


    }


}
